/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function (s) {
  let ans = 0
  let hash = {}
  for (let i = 0, j = 0; j < s.length; j++) {
    // 如果存在
    if (hash[s[j]] !== undefined) {
      i = Math.max(hash[s[j]], i)
    }
    // 没命中，看窗口长度
    ans = Math.max(ans, j - i + 1)
    hash[s[j]] = j + 1
  }
  return ans
};

/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function (s) {
  let left = right = length = maxLength = 0
  const set = new Set()
  while (right < s.length) { //右指针在数据长度内
    if (!set.has(s[right])) { //没有右指针的元素
      set.add(s[right]) //set中存入右指针元素
      length++ //长度增加
      if (length > maxLength) maxLength = length //新的最长长度
      right++ //右指针往后移动
    } else {
      while (set.has(s[right])) { //如果set中有右指针元素
        set.delete(s[left]) //set中删除左指针元素
        left++ //左指针增加
        length-- //长度减少
      }
      set.add(s[right]) //set中存入右指针
      length++ //长度增加
      right++ //右指针往后移动
    }
  }
  return maxLength
};